package com.killer.catalina;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * @author ：Killer
 * @date ：Created in 20-11-9 下午4:44
 * @description：${description}
 * @modified By：
 * @version: version
 */
public class Catalina{

    /**
     * catalina配置文件路径
     */
    protected String configFile = "conf/server.xml";

    /**
     * 按照tomcat配置文件server.xml，一个Catalina下面有一个Server
     */
    private Server server;

    public Server getServer() {
        return server;
    }

    public void setServer(Server server) {
        this.server = server;
    }

    /**
     * 加载server.xml配置信息
     */
    public void load() throws DocumentException, FileNotFoundException {
        //读取xml配置文件
        File file=loadConfigFile();
        if (!file.exists()) {
            throw new RuntimeException("没找到配置文件server.xml");
        }
        FileInputStream inputStream = new FileInputStream(file);
        SAXReader reader = new SAXReader();
        Document document = reader.read(inputStream);
        //根标签就是Server标签
        Element rootElement = document.getRootElement();
        StandardServer server=new StandardServer();
        //解析下面的Service标签
        server.setServiceList(parseService(rootElement));
        this.server=server;
    }

    private File loadConfigFile() {
        //获取MinCat目录
        String homeDir = System.getProperty("catalina.home");
        String filePath= StringUtils.isBlank(homeDir)?"."+File.separator+configFile:homeDir+File.separator+configFile;
        return new File(filePath);
    }

    public List<Service> parseService(Element element){
        List<Element> serviceElements = element.selectNodes("Service");
        List<Service> services = new ArrayList<Service>();
        if (CollectionUtils.isNotEmpty(serviceElements)) {
            for (Element serviceElement : serviceElements) {
                StandardService service=new StandardService();
                String name = serviceElement.attributeValue("name");
                service.setName(name);
                //解析connector标签
                service.setConnectors(parseConnector(serviceElement, service));
                //解析engine标签
                service.setEngine(parseEngine(serviceElement));
                services.add(service);
            }
        }
        return services;
    }

    public Engine parseEngine(Element element) {
        Element engineElement = (Element)element.selectSingleNode("Engine");
        if (engineElement != null) {
            StandardEngine engine = new StandardEngine();
            //解析host标签
            engine.setHosts(parseHost(engineElement));
            return engine;
        }
        return null;
    }


    public List<Host> parseHost(Element element) {
        List<Element> hostElements = element.selectNodes("Host");
        List<Host> hosts = new ArrayList<Host>();
        if (CollectionUtils.isNotEmpty(hostElements)) {
            for (Element hostElement : hostElements) {
                StandardHost host=new StandardHost();
                String name = hostElement.attributeValue("name");
                String appBase = hostElement.attributeValue("appBase");
                host.setAppBase(appBase);
                host.setName(name);
                //解析Context标签
                host.setContextList(parseContext(hostElement,host));
                hosts.add(host);
            }
        }
        return hosts;
    }

    public List<Context> parseContext(Element element,StandardHost host) {
//        <Context docBase="sample-demo" path="/sample-demo" reloadable="true" source="org.eclipse.jst.jee.server:sample-demo"/>
        List<Element> contextElements = element.selectNodes("Context");
        List<Context> contexts = new ArrayList<Context>();
        if (CollectionUtils.isNotEmpty(contextElements)) {
            for (Element contextElement : contextElements) {
                StandardContext context=new StandardContext();
                String docBase = contextElement.attributeValue("docBase");
                String path = contextElement.attributeValue("path");
                context.setDocBase(docBase);
                context.setPath(path);
                context.setHost(host);
                contexts.add(context);
            }
        }
        return contexts;

    }

    public List<Connector> parseConnector(Element element,Service service) {
        List<Element> connectorElements = element.selectNodes("Connector");
        List<Connector> connectors = new ArrayList<Connector>();
        if (CollectionUtils.isNotEmpty(connectorElements)) {
            for (Element connectorElement : connectorElements) {
                Connector connector=new Connector();
                connector.setService(service);
                int port = Integer.parseInt(connectorElement.attributeValue("port"));
                connector.setPort(port);
                connectors.add(connector);
            }
        }
        return connectors;
    }

    /**
     * 启动Catalina容器
     */
    public void start(){
        //启动下面的Server
        getServer().start();
    }
}
